package project3.datasets.parsers;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashSet;
import java.util.Set;

import project3.datasets.Attribute;
import project3.datasets.DiscreteAttribute;
import project3.datasets.Instance;
import project3.util.UncheckedException;

/**
 * @author Antonio
 * @author Vika
 * 
 */
public class CsvParser implements DataSetParser {

	private Attribute[] attributes;

	private final String dataSetName;

	/**
	 * @param dataSetName
	 * @param fileName
	 */
	public CsvParser(String dataSetName, String fileName) {
		this.dataSetName = dataSetName;

		try {
			BufferedReader reader = new BufferedReader(
					new FileReader(fileName));

			String title = reader.readLine();

			String[] tokens = title.split(",");
			this.attributes = new Attribute[tokens.length];
			for (int i = 0; i < attributes.length; i++) {
				String[] categories = loadCategoriesForIndex(i, fileName);
				attributes[i] = new DiscreteAttribute(i, tokens[i], categories);
			}
			
			this.reader = new BufferedReader(new FileReader(fileName));

			//skip title
			this.reader.readLine();


		} catch (IOException ex) {
			throw new UncheckedException(ex);
		}
	}

	/**
	 * @param index
	 * @param fileName
	 * @return
	 */
	private static String[] loadCategoriesForIndex(int index, String fileName) {
		try {
			Set<String> categories = new HashSet<String>();

			BufferedReader reader = new BufferedReader(new FileReader(fileName));

			String line = reader.readLine();// first line, we don't care

			while ((line = reader.readLine()) != null) {
				String[] tokens = line.split(",");

				if (index < tokens.length)
					categories.add(tokens[index]);
			}

			//Trace.info("Categories: " + categories.toString());

			return categories.toArray(new String[categories.size()]);
		} catch (IOException e) {
			e.printStackTrace();

			throw new UncheckedException(e);
		}
	}

	public String getDataSetName() {
		return dataSetName;
	}

	public Attribute[] getAttributes() {
		return this.attributes.clone();
	}

	private BufferedReader reader;


	/* (non-Javadoc)
	 * @see project3.datasets.parsers.DataSetParser#nextRow()
	 */
	public Instance nextRow() {
		try {
			String line;
			if ((line = reader.readLine()) != null) {
				String[] tokens = line.split(",");
				double[] values = new double[attributes.length];

				for (int i = 0; i < this.attributes.length; i++) {
					if(i < tokens.length && !tokens[i].equals(""))
				    	values[i] = ((DiscreteAttribute) this.attributes[i])
						.encode(tokens[i]);
					else
				    	values[i] = ((DiscreteAttribute) this.attributes[i])
						.encode(null);
				}

				return new Instance(values);
			}
			
			return null;

		} catch (IOException ex) {
			throw new UncheckedException(ex);
		}

	}

}
